package org.freemarker.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.freemarker.core.model.Car;
import org.freemarker.core.service.CarService;
import org.freemarker.core.validator.Validator;
import org.freemarker.web.custom.CustomHttpServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartRequest;

@Controller
public class CarAddController extends CustomHttpServlet {
	public static String carImgPath = "D:\\projects\\freemarker_tut\\src\\main\\webapp\\WEB-INF\\resources\\images\\cars";

	private static final long serialVersionUID = -4559740868178370249L;

	@Autowired
	private CarService carService;
	private Validator validator = new Validator();

	
//	 @Override
//	 public void init(ServletConfig servletConfig) throws ServletException {
//	 super.init(servletConfig);
//	 }

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		req.getRequestDispatcher("views/car/addCars.ftl").forward(req, resp);
	}

	@Override
	/**
	 * processes the MULTIPART request
	 * Reads the car info 
	 * Creates and saves the car if it is valid
	 * Uploads the file in the request if it is an image(.jpg, .png, .gif)
	 */
	protected void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		HashMap<String, String> values = new HashMap<String, String>();
		Car car = new Car();
		FileItem uploadedFileItem = null;

		/*
		 * parse the multipart request
		 */
		try {
			List<FileItem> items = upload.parseRequest(req);
			Iterator<FileItem> iterator = items.iterator();
			while (iterator.hasNext()) {
				FileItem item = iterator.next();
				if (!item.isFormField()) {// save the item
					uploadedFileItem = item;
				} else {// store the name-value pairs of the form fields
					values.put(item.getFieldName(), item.getString());
				}
			}
			// set car mermbers
			car.setMarca(values.get("marca"));
			car.setModel(values.get("model"));
			car.setNumarMatricol(values.get("numarMatricol"));
		} catch (Exception e) {
			e.printStackTrace();
		}

		/*
		 * verify and save the uploaded data
		 */
		List<String> errors = new ArrayList<String>();
		errors = validateCarData(car);
		if (errors.size() == 0) {
			carService.save(car);

			String fileName = uploadedFileItem.getName();
			if (fileName.length() > 0) {
				boolean valid = isValidImageFileName(fileName);
				if (!valid) {
					errors.add("Uploaded file is not an image file!");
				} else {
					// save the uploaded img with a name like: carID.extension
					Long carId = carService.getCarForNr(car.getNumarMatricol())
							.getId();
					fileName = carId.toString()
							+ fileName.substring(fileName.lastIndexOf("."));
					saveFileItem(uploadedFileItem, fileName);
					car.setImageName(fileName);
					carService.update(car);
				}

			}

		}
		List<Car> cars = carService.findAll();
		req.setAttribute("carImgFolder", "spring/resources/images/cars");
		req.setAttribute("cars", cars);
		req.setAttribute("errors", errors);
		req.getRequestDispatcher("views/car/listCars.ftl").forward(req, res);
	}

	public boolean isValidImageFileName(String fileName) {
		String[] extensions = { ".gif", ".jpg", ".png" };
		boolean valid = false;
		for (int i = 0; i < extensions.length; i++) {
			if (fileName.endsWith(extensions[i])) {
				valid = true;
				break;
			}
		}
		return valid;
	}

	/**
	 * Validates car data
	 * 
	 * @param car
	 * @return List of error messages
	 */
	public List<String> validateCarData(Car car) {
		List<String> errors = validator.checkCarData(car);
		try {
			if (carService.getCarForNr(car.getNumarMatricol()) != null) {
				errors.add("Plate number already in database!");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return errors;
	}

	/**
	 * Saves the file uploaded in the request at the path in carImgPath
	 * 
	 * @param item
	 * @param id
	 */
	public void saveFileItem(FileItem item, String fileName) {
		String root = getServletContext().getRealPath("/");

		// path where the file will be stored
		File path = new File(carImgPath);
		if (!path.exists()) {
			boolean status = path.mkdirs();
		}

		File uploadedFile = new File(carImgPath + "/" + fileName);
		if (!uploadedFile.exists())
			try {
				item.write(uploadedFile);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}
}
